[Java][Spring Boot] Criteria APIでJavaらしくデータベースを検索。
はじめに
これまでのJPQLに関する記事は、クエリを"from MyData where id = :id"の様に文字で書いていました。 SQLをほぼそのままなので分かりやすいと言えばそうなのですが、Javaとしてどうなのかと言われると疑問です。 EclipseなどのIDEの自動エラーチェックにも引っかからないので、スペルミスでコンパイルが通らなくて原因解明に時間を取られる...なんて事は無くしたいです。 そこで今回は、JPAが実装しているCriteria APIを使用して、Javaらしいクエリの作成と実行を試してみたいと思います。
環境
Mac OSX 10.10.5 Yosemite Eclipse Mars2 Java 8 Spring Boot 1.3.6 PostgreSQL 9.5.1
テーブル準備
PostgreSQLで作成しました。
CREATE TABLE fruit ( id VARCHAR(2) NOT NULL, name VARCHAR(10), price integer, PRIMARY KEY(id) ); INSERT INTO fruit VALUES ('1','apple',300), ('2','orange',200), ('3','banana',100), ('4','cherry',100), ('5','pineapple',500), ('6','melon',800), ('7','watermelon',600), ('8','strawberry',450) ;
postgres=# select * from fruit ; id | name | price ----+------------+------- 1 | apple | 300 2 | orange | 200 3 | banana | 100 4 | cherry | 50 5 | pineapple | 500 6 | melon | 800 7 | watermelon | 600 8 | strawberry | 450 (8 rows)
コード
エンティティ
package com.jpa.mydao; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; @Entity @Data @Table(name="fruit") public class Fruit { @Id private String id; private String name; private Integer price; }
今回もlombokの@DataでGetter/Setterを生成しています。
DAOインターフェース
package com.jpa.mydao.dao; import java.io.Serializable; import java.util.List; public interface FruitDao <T> extends Serializable { public List<T> getAll(); }
DAOオブジェクト
package com.jpa.mydao.dao; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.jpa.mydao.Fruit; @Repository public class FruitDaoJpql implements FruitDao<Fruit>{ private EntityManager entityManager; public FruitDaoJpql() { } public FruitDaoJpql(EntityManager entityManager) { this.entityManager = entityManager; } @Override public List<Fruit> getAll() { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Fruit> query = builder.createQuery(Fruit.class); Root<Fruit> root = query.from(Fruit.class); query.select(root); List<Fruit> list = (List<Fruit>) entityManager.createQuery(query).getResultList(); return list; } }
基本の流れは下記になっている様です。 builder -> query -> root -> メソッド実行 -> 結果を取得
29~37行目はDAOインターフェースで作成したメソッドです。 31行目、CriteriaBuilder。クエリ生成の管理クラス。 32行目、CriteriaQuery。クエリ実行のクラス。 33行目、Root。ここからエンティティの絞り込みなどを行います。 34行目、クエリの生成。テーブル検索の準備完了です。 35行目、クエリを実行してListで取得。 SQLだと、"select * from fruit;"となります。
コントローラー
package com.jpa.mydao; import java.util.List; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.jpa.mydao.dao.FruitDaoJpql; @RestController public class EntityManagerController { @PersistenceContext EntityManager entityManager; FruitDaoJpql dao; @PostConstruct public void init() { dao = new FruitDaoJpql(entityManager); } @RequestMapping(value="/all", method=RequestMethod.GET) public List<Fruit> all() { List<Fruit> list = dao.getAll(); return list; } }
"http://localhost:8080/all"で呼ばれるメソッドが一つだけです。 30行目、DAOオブジェクトからgetAll()を実行してListで取得しています。
実行
$ curl http://localhost:8080/all [{"id":"1","name":"apple","price":300},{"id":"2","name":"orange","price":200},{"id":"3","name":"banana","price":100},{"id":"4","name":"cherry","price":50},{"id":"5","name":"pineapple","price":500},{"id":"6","name":"melon","price":800},{"id":"7","name":"watermelon","price":600},{"id":"8","name":"strawberry","price":450}]
さいごに
SQLが読めれば、後は処理の流れを覚えるだけで良さそうです。 次回は、より詳細な検索を試してみたいと思います。